package com.jueling.culture.core;



import com.jueling.culture.exception.FrontShowException;
import com.jueling.culture.exception.TokenErrResolveException;
import com.jueling.culture.exception.TokenResolveException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 全局异常捕捉处理
 * @author linp
 * @date 2018/10/11
 */
@ControllerAdvice
public class GlobalControllerAdvice {

    /**
     * 全局异常捕捉处理
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result errorHandler(Exception ex  , HttpServletRequest request, HttpServletResponse response) {
        proccess(request, response);
        ex.printStackTrace();
        return ResultGenerator.genFailResult(ex.getMessage());
    }
    /**
     * 前端直接显示
     *
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = FrontShowException.class )
    public Result errorHandler(FrontShowException ex  , HttpServletRequest request, HttpServletResponse response){
        proccess(request, response);
        return ResultGenerator.genFrontShowResult(ex.getMessage());
    }

    /**
     * token异常处理
     * @param ex
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = TokenResolveException.class)
    public Result errorHandler(TokenResolveException ex , HttpServletRequest request, HttpServletResponse response){
        proccess(request, response);
        return ResultGenerator.genUnauthorizedResult(ex.getMessage());
    }

    /**
     * refreshToken异常处理
     * @param ex
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = TokenErrResolveException.class)
    public Result errorHandler(TokenErrResolveException ex , HttpServletRequest request, HttpServletResponse response){
        proccess(request, response);
        return ResultGenerator.genRefreshTokenFail(ex.getMessage());
    }

    /**
     * 参数校验不通过
     *
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result errorHandler(MethodArgumentNotValidException ex) {
        StringBuffer sb = new StringBuffer();
        BindingResult result = ex.getBindingResult();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            for (ObjectError error : errors) {
                sb.append(error.getDefaultMessage());
                break;
            }
        }
        return ResultGenerator.genBadResult(sb.toString());
    }

    /**
     * 参数类型错误
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public Result errorHandler(MethodArgumentTypeMismatchException ex) {
        String localizedMessage = ex.getLocalizedMessage();
        return ResultGenerator.genBadResult(localizedMessage);
    }

    /**
     * 缺少参数
     *
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public Result errorHandler(MissingServletRequestParameterException ex) {
        String localizedMessage = ex.getLocalizedMessage();
        return ResultGenerator.genBadResult(localizedMessage);
    }

        /**
         * 全局异常后跨域解决
         * @param request
         * @param response
         */
    private void proccess(HttpServletRequest request, HttpServletResponse response) {
        String originHeader=request.getHeader("Origin");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        response.setStatus(200);
        response.setHeader("Access-Control-Expose-Headers", "verifyCode");
        response.setHeader("Access-Control-Allow-Origin",originHeader);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");


    }

}
